package translation;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import libraries.LibraryContainer;



public class Circuit {

	
	NetSystem netSys;
	PartSystem partSys;
	
	
	public NetSystem getNetSys() {
		return netSys;
	}
	public PartSystem getPartSys() {
		return partSys;
	}
	
	/**
	 * Reads the given files and fills the NetSystem and PartSystem with the obtained data
	 * @param partList a file of an EAGLE partList
	 * @param NetList a file of an EAGLE netList
	 * @throws IOException
	 */
	public void readCircuit(File partList, File NetList) throws IOException {
		//Part lists must always be read first since net list creation needs an existent part list
		partSys.readPartList(partList);
		netSys.readNetList(NetList);
	}
	
	/**
	 * Writes the associated PartList and NetList to a modelica file
	 * @param output a file to which the model is written
	 * @param name the model name
	 * @throws IOException
	 */
	public void writeCircuit(File output, String name) throws IOException {
		BufferedWriter out = null;
		try {
			out = new BufferedWriter(new FileWriter(output));
			//out.write("within ;\npackage Elect\n\n //  import Modelica.SIUnits.*;\n");
			out.write("model " + name);
			out.newLine();
			String comments = getPartSys().writePartList(out);
			out.write("equation\n");
			getNetSys().writeNetList(out);
			out.write(comments);
			out.write("end " + name + ";\n");
			//out.write("end Elect;\n");
		} finally {
			if (out != null) {
				out.close();
			}
		}
		
				
		//String out = "within ;\npackage Elect\n\n //  import Modelica.SIUnits.*;\n";
		//out += "model " + name + "\n";
		//out += getPartSys().writePartList(out)
		
	}
	
	/**
	 * 
	 * @param lib a reference to the libraries used in the translation
	 */
	public Circuit(LibraryContainer lib) {
		super();
		this.partSys = new PartSystem(lib);
		this.netSys = new NetSystem(this);
	}
	
	/**
	 * does a testrun on the primary translation, library import and export functions using 
	 * the files "Test_InputLibrary.edl", "Test_Partlist" and "Test_Netlist", all of them 
	 * located in the same directory as the .jar file. The library is exported to 
	 * "Test_OutputLibrary.edl", the model is written to "Test_DY.mo"
	 */
	private static void testRun(){
		//		LibraryContainer lib = LibraryContainer.testLibraryContainer();
			LibraryContainer lib = new LibraryContainer();
		try {
			//			lib.readLibrary(new File ("D:\\Bachelor\\EAGLE\\Beispiele\\Test\\stuffLib"));
			lib.readLibraryFile(new File ("Test_InputLibrary.edl"));
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		Circuit circ = new Circuit(lib);
		try{
			//			lib.writeLibrary(new File ("D:\\Bachelor\\EAGLE\\Beispiele\\Test\\stuffLib2"), "Test_Library");
			//			circ.getPartSys().readPartList(new File ("D:\\Bachelor\\EAGLE\\Beispiele\\Test\\stuffPart"));
			//			circ.getNetSys().readNetList(new File ("D:\\Bachelor\\EAGLE\\Beispiele\\Test\\stuffNet"));
			//			circ.writeCircuit(new File ("D:\\Bachelor\\EAGLE\\Beispiele\\Test\\stuffDYM.mo"), "Stuff");

			lib.writeLibraryFile(new File ("Test_OutputLibrary.edl"), "Test_Library");
			circ.getPartSys().readPartList(new File ("Test_Partlist"));
			circ.getNetSys().readNetList(new File ("Test_Netlist"));
			circ.writeCircuit(new File ("Test_DY.mo"), "Test_DY");
		}  catch (IOException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}
	}
	
	private static void GUITestRun(File partList, File netList, File save, LibraryContainer lib){
		//hardcode
				boolean HC = true;
				if (HC) {
//					LibraryContainer lib = LibraryContainer.testLibraryContainer();
					//LibraryContainer lib = new LibraryContainer();
					try {
						lib.readLibraryFile(new File ("D:\\Bachelor\\EAGLE\\Beispiele\\Test\\stuffLib"));
						
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					Circuit circ = new Circuit(lib);
					try{
						lib.writeLibraryFile(new File ("D:\\Bachelor\\EAGLE\\Beispiele\\Test\\stuffLib2"), "Test_Library");
						circ.getPartSys().readPartList(partList);
						circ.getNetSys().readNetList(netList);
						circ.writeCircuit(save, "Test_file");
						
					}  catch (IOException e2) {
						// TODO Auto-generated catch block
						e2.printStackTrace();
					}

				} else {
					//		LibraryContainer lib = LibraryContainer.testLibraryContainer();
					//LibraryContainer lib = new LibraryContainer();
					try {
						//			lib.readLibrary(new File ("D:\\Bachelor\\EAGLE\\Beispiele\\Test\\stuffLib"));

						lib.readLibraryFile(new File ("Test_InputLibrary.edl"));
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					Circuit circ = new Circuit(lib);
					try{
						//			lib.writeLibrary(new File ("D:\\Bachelor\\EAGLE\\Beispiele\\Test\\stuffLib2"), "Test_Library");
						//			circ.getPartSys().readPartList(new File ("D:\\Bachelor\\EAGLE\\Beispiele\\Test\\stuffPart"));
						//			circ.getNetSys().readNetList(new File ("D:\\Bachelor\\EAGLE\\Beispiele\\Test\\stuffNet"));
						//			circ.writeCircuit(new File ("D:\\Bachelor\\EAGLE\\Beispiele\\Test\\stuffDYM.mo"), "Stuff");

						lib.writeLibraryFile(new File ("Test_OutputLibrary.edl"), "Test_Library");
						circ.getPartSys().readPartList(new File ("Test_Partlist"));
						circ.getNetSys().readNetList(new File ("Test_Netlist"));
						circ.writeCircuit(new File ("Test_DY.mo"), "Test_Circuit");
					}  catch (IOException e2) {
						// TODO Auto-generated catch block
						e2.printStackTrace();
					}
				}
			}
	
	/**
	 * creates a Circuit object, reads an EAGLE partlist and netlist, 
	 * translates them and outputs into a modelica file
	 * @param partList a file of an EAGLE partList
	 * @param NetList a file of an EAGLE netList
	 * @param save the location where the modelica file is saved
	 * @param lib the library container to be used in translating
	 */
	public static void translate(File partList, File netList, File save, LibraryContainer lib){
		Circuit circ = new Circuit(lib);
		try{
			circ.getPartSys().readPartList(partList);
			circ.getNetSys().readNetList(netList);
			circ.writeCircuit(save, save.getName().substring(0, save.getName().length()-3));
			
		}  catch (IOException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}
	}

	
	/**
	 * tests the library and translation functions using the testRun() function
	 * @param args
	 */
	public static void main(String[] args) {
		testRun();
	}
	
}
